using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using PACKETPARSERMAX20.CORE;

namespace PACKETPARSERMAX20.WinUI
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        public struct ProcessLogsArgs
        {
            public PACKETPARSERMAX20.CORE.DefinitionProcessor[] definitionProcessorArray;
            public bool resume;
        }

        //public delegate void DelegateProcessLogsResume(PACKETPARSERMAX20.CORE.DefinitionProcessor[] readerarray, bool resume);
        //public delegate void DelegateProcessLogs(PACKETPARSERMAX20.CORE.DefinitionProcessor[] readerarray);
        // public event DelegateProcessLogs EventProcessLogs = null;
        public delegate void DeletageUpdateViewer();

        private frmViewer FormViewer = null;
        private frmStatus FormStatus = new frmStatus();
        private frmLogList FormLogList = new frmLogList();
        private frmPacketList FormPacketList = new frmPacketList();
        private frmWarningPacketList FormWarningPacketList = new frmWarningPacketList();
        private frmFilter FormFilter = new frmFilter();
        private frmHex FormHex = new frmHex();
        private System.Threading.Thread ProcessThread = null;
        private PACKETPARSERMAX20.CORE.DefinitionProcessor DefinitionProcessor = null;
        private bool IsUpdating = false;


        private void Init()
        {
            txtPacketMaxProcessCount.Text = StaticObjects.PacketMaxProcessCount.ToString();
            chkRefreshRadar.Checked = StaticObjects.RefreshRadar;


            StaticObjects.eventManager = new PACKETPARSERMAX20.EventManager();
            StaticObjects.eventManager.EventUpdateStatusLog += new EventManager.DelegateUpdateStatusLog(UpdateStatusLog);
            if (FormViewer != null)
            {
                StaticObjects.eventManager.EventObject_Updated += new EventManager.DelegateObject_Updated(FormViewer.UpdateViewer);
            }
            StaticObjects.eventManager.EventCurrentPacketIndex += new EventManager.DelegateCurrentPacketIndex(eventManager_EventCurrentPacketIndex);
            chkSilentMode.Checked = StaticObjects.eventManager.SilentMode;

            //FormLogList.Init(new string[] { @"H:\DATA\SQLITE\dbs\" });//, EventProcessLogs);

            FormLogList.Init(new string[] { @"E:\Upload\WOWDEV\SNIFFS\7561\" });//, EventProcessLogs);

            FormPacketList.Init();
            FormWarningPacketList.Init();
            FormHex.Init();
            FormFilter.Init();
        }

        private void ProcessLogs(object param)
        {
            var processLogsArgs = (ProcessLogsArgs)param;

            ProcessLogs(processLogsArgs.definitionProcessorArray, processLogsArgs.resume);
        }

        private void ProcessLogs(DefinitionProcessor[] readerarray, bool resume)
        {
            if (readerarray != null)
            {
                foreach (DefinitionProcessor tProcessor in readerarray)
                {
                    if (resume) { if (DefinitionProcessor != tProcessor) continue; }
                    int build = 0;
                    if (!StaticObjects.CorruptLogList.Contains(tProcessor.Reader.Name))
                    {
                        build = tProcessor.Reader.ClientBuild;
                        ProcessLog(tProcessor);
                        if (StaticObjects.eventManager.Pause) { break; }
                        if (tProcessor.Reader.Total == tProcessor.Reader.CurrentIndex) tProcessor.Reset();
                        GC.Collect();
                    }
                }
            }
        }

        private void ProcessLog(DefinitionProcessor reader)
        {
            if (reader.Reader.Total > 0)
            {
                FormLogList.UpdateLog(reader);
                reader.Reader.MaxProcessCount = StaticObjects.PacketMaxProcessCount;
                DefinitionProcessor = reader;
                reader.Process();
            }
            UpdateViewer();
        }

        private void UpdateViewer()
        {
            if (InvokeRequired)
            {
                DeletageUpdateViewer tdelegate = new DeletageUpdateViewer(UpdateViewer);
                this.Invoke(tdelegate);
            }
            else
            {
                IsUpdating = true;
                if (DefinitionProcessor != null)
                {

                    txtPacketIndex.Text = DefinitionProcessor.Reader.CurrentIndex.ToString();
                    txtPacketMaxProcessCount.Text = DefinitionProcessor.Reader.MaxProcessCount.ToString();
                }
                IsUpdating = false;

            }
        }

        private void UpdateStatusLog(string time, string message, bool attention)
        {
            FormStatus.UpdateStatusLog(time, message, attention);
        }

        private void InitForms()
        {

            FormStatus.MdiParent = this;
            FormStatus.Show(dpMainMdi);

            FormLogList.MdiParent = this;
            FormLogList.Show(dpMainMdi);

            FormPacketList.MdiParent = this;
            FormPacketList.Show(dpMainMdi);

            FormWarningPacketList.MdiParent = this;
            FormWarningPacketList.Show(dpMainMdi);

            FormHex.MdiParent = this;
            FormHex.Show(dpMainMdi);

            FormFilter.MdiParent = this;
            FormFilter.Show(dpMainMdi);

            FormPacketList.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;
            FormPacketList.VisibleState = WeifenLuo.WinFormsUI.Docking.DockState.Document;

            FormWarningPacketList.Text = "Warning Packet List";
            FormWarningPacketList.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;
            FormWarningPacketList.VisibleState = WeifenLuo.WinFormsUI.Docking.DockState.Document;

            FormLogList.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockLeft;
            FormLogList.VisibleState = WeifenLuo.WinFormsUI.Docking.DockState.DockLeft;

            FormStatus.DockState = WeifenLuo.WinFormsUI.Docking.DockState.DockBottom;
            FormStatus.VisibleState = WeifenLuo.WinFormsUI.Docking.DockState.DockBottom;

            FormHex.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;
            FormHex.VisibleState = WeifenLuo.WinFormsUI.Docking.DockState.Document;

            FormFilter.DockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;
            FormFilter.VisibleState = WeifenLuo.WinFormsUI.Docking.DockState.Document;

            FormPacketList.BringToFront();

            //FormLogList.Size = new Size(600, FormLogList.Size.Height);
            //FormLogList.Width = 10000;
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            FormViewer = new PACKETPARSERMAX20.WinUI.frmViewer();
            FormViewer.Show();

            StaticObjects.RefreshRadar = chkRefreshRadar.Checked;
            InitForms();
            Init();

        }

        private void btnProcessSQLiteLogs_Click(object sender, EventArgs e)
        {
            ProcessThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ProcessLogs));
            ProcessLogsArgs param = new ProcessLogsArgs() { definitionProcessorArray = FormLogList.GetItems(), resume = false };
            ProcessThread.Start((object)param);
        }

        private void btnProcessSelected_Click(object sender, EventArgs e)
        {
            if (ProcessThread == null || !ProcessThread.IsAlive)
            {
                ProcessThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ProcessLogs));
                ProcessLogsArgs param = new ProcessLogsArgs() { definitionProcessorArray = FormLogList.CheckedItems, resume = false };
                ProcessThread.Start((object)param);
            }
            else
            {

            }
        }

        private void btnPreviousPacketSet_Click(object sender, EventArgs e)
        {
            //
        }

        private void btnNextPacketSet_Click(object sender, EventArgs e)
        {
            //
        }

        private void txtPacketIndex_TextChanged(object sender, EventArgs e)
        {
            if (!IsUpdating)
            {
                if (DefinitionProcessor != null)
                {
                    int tout = 0;
                    if (int.TryParse(txtPacketIndex.Text, out tout))
                    {
                        DefinitionProcessor.Reader.CurrentIndex = tout;
                    }
                }
            }
        }

        private void txtPacketMaxProcessCount_TextChanged(object sender, EventArgs e)
        {

            if (!IsUpdating)
            {
                int tout = 0;
                if (int.TryParse(txtPacketMaxProcessCount.Text, out tout))
                {
                    StaticObjects.PacketMaxProcessCount = tout;
                }
                //if (DefinitionProcessor != null)
                //{

                //        DefinitionProcessor.MaxProcessCount = mPacketMaxProcessCount;

                //}
            }
        }

        private void chkSilentMode_Click(object sender, EventArgs e)
        {
            UpdateSilenMode();
        }

        public void UpdateSilenMode()
        {
            StaticObjects.eventManager.SilentMode = chkSilentMode.Checked;
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            if (StaticObjects.eventManager != null)
            {
                StaticObjects.eventManager.EventUpdateStatusLog -= new EventManager.DelegateUpdateStatusLog(UpdateStatusLog);
                // EventProcessLogs -= new DelegateProcessLogs(ProcessLogs);
            }

            StaticObjects.eventManager = new PACKETPARSERMAX20.EventManager();
            StaticObjects.eventManager.EventUpdateStatusLog += new EventManager.DelegateUpdateStatusLog(UpdateStatusLog);
            //StaticObjects.mConfig = new PACKETPARSERMAX20.CORE.Config(StaticObjects.eventManager);
            //StaticObjects.mDataAcces = StaticObjects.mConfig.GetDaAccess();
            //Common.descriptors = new Descriptors(StaticObjects.mDataAcces);

            FormLogList.Init(new string[] { @"C:\BASE\DEV\SVN\SQLITE\dbs\", "H:\\DATA\\SQLITE\\dbs\\", "H:\\DATA\\WISP\\CONVERTEDLOGS\\A\\" });//, EventProcessLogs);
            FormPacketList.Init();
            FormHex.Init();
            FormFilter.Init();
        }


        public System.Data.DataTable ExecuteGetDataTable(string pCommandText, string pConnectionstring)
        {
            MySql.Data.MySqlClient.MySqlConnection tConnection = new MySql.Data.MySqlClient.MySqlConnection(pConnectionstring);
            MySql.Data.MySqlClient.MySqlDataAdapter tAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter(pCommandText, tConnection);
            //tAdapter.UpdateBatchSize = 500;
            tAdapter.ContinueUpdateOnError = false;
            System.Data.DataTable tDataTable = new System.Data.DataTable();
            tConnection.Open();
            tAdapter.Fill(tDataTable);
            tConnection.Close();
            return tDataTable;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {

            string tConnectionString = "allow batch=True;Database=dbc_332;User Id=root;Password=root;Server=MIKEDB01;Port=3306;Persist Security Info=False";
            string tRequest = "Select `id`, `parentMap` as `mapid`, `parentZone` as `areatableid`, `name` from  `areatable` order by `id`";

            System.Data.DataTable tAreaTable = ExecuteGetDataTable(tRequest, tConnectionString);//.Execute("Select id, mapid, areatableid, name from dbc_2_0_1.dbc_areatable order by id");
            System.Xml.XmlDocument tDom = new System.Xml.XmlDocument();
            tDom.AppendChild(tDom.CreateElement("areas"));
            foreach (System.Data.DataRow tRow in tAreaTable.Rows)
            {
                System.Xml.XmlElement telement = tDom.CreateElement("area");
                telement.SetAttribute("id", tRow["id"].ToString());
                telement.SetAttribute("mapid", tRow["mapid"].ToString());
                telement.SetAttribute("areatableid", tRow["areatableid"].ToString());
                telement.SetAttribute("name", tRow["name"].ToString());
                tDom.DocumentElement.AppendChild(telement);

                //System.Diagnostics.Debug.WriteLine("case " + tRow["mapid"].ToString() + ": area = \"" + tRow["name"].ToString() + "\"; break;");

            }

            tDom.Save(System.AppDomain.CurrentDomain.BaseDirectory + "areatable.xml");


            tRequest = "Select `id`, `name_internal` as `internalname` from  `map` order by `id`";

            System.Data.DataTable tmap = ExecuteGetDataTable(tRequest, tConnectionString);//.Execute("Select id, mapid, areatableid, name from dbc_2_0_1.dbc_areatable order by id");

            System.Xml.XmlDocument tDomMap = new System.Xml.XmlDocument();
            tDomMap.AppendChild(tDomMap.CreateElement("maps"));
            foreach (System.Data.DataRow tRow in tmap.Rows)
            {
                System.Xml.XmlElement telement = tDomMap.CreateElement("map");
                telement.SetAttribute("id", tRow["id"].ToString());
                telement.SetAttribute("name", tRow["internalname"].ToString());
                tDomMap.DocumentElement.AppendChild(telement);

                System.Diagnostics.Debug.WriteLine("case " + tRow["id"].ToString() + ": area = \"" + tRow["internalname"].ToString() + "\"; break;");

            }

            //tDomMap.Save(System.AppDomain.CurrentDomain.BaseDirectory + "map.xml");
        }

        private void eventManager_EventCurrentPacketIndex(int pIndex)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new EventManager.DelegateCurrentPacketIndex(eventManager_EventCurrentPacketIndex), pIndex);
            }
            else
            {
                lblCurrentPacketIndex.Text = "Current Packet Index: " + pIndex.ToString();
            }
        }

        private void chkRefreshRadar_CheckedChanged(object sender, EventArgs e)
        {
            StaticObjects.RefreshRadar = chkRefreshRadar.Checked;
        }

        private void toolStripButton1_Click_1(object sender, EventArgs e)
        {
            StaticObjects.RefreshRadar = false;
            StaticObjects.eventManager.SilentMode = true;

            for (int i = 0; i <= (int)Opcodes.NUM_MSG_TYPES; i++)
            {
                if (!StaticObjects.opcodeFilter.Contains((Opcodes)i))
                {
                    StaticObjects.opcodeFilter.Add((Opcodes)i);
                }
            }

            StaticObjects.opcodeFilter.Remove(Opcodes.SMSG_GAMEOBJECT_QUERY_RESPONSE);

            ProcessLogs(FormLogList.GetItems());

            System.Xml.XmlDocument tDom = new System.Xml.XmlDocument();
            tDom.AppendChild(tDom.CreateElement("GameObjects"));
            foreach (PACKETPARSERMAX20.CORE.GameObjectTemplateSum tObj in PACKETPARSERMAX20.CORE.GlobalCache.GameObjectTemplateSumList.Values)
            {
                System.Xml.XmlElement tElement = tDom.CreateElement("GameObject");
                tElement.SetAttribute("entry", tObj.entry.ToString());
                tElement.SetAttribute("name", tObj.name);
                tElement.SetAttribute("typeid", tObj.typeid.ToString());
                tDom.DocumentElement.AppendChild(tElement);
            }
            tDom.Save(".\\gameobjects.xml");
        }



        //private void toolStripButton3_Click(object sender, EventArgs e)
        //{

        //    if (System.IO.File.Exists("customlist.log"))
        //    {
        //        System.IO.StreamReader sr = new System.IO.StreamReader("customlist.log");

        //        List<string> list = new List<string>();
        //        int i = 10;
        //        while (!sr.EndOfStream && i != 0)
        //        {
        //            list.Add(sr.ReadLine());
        //            i--;
        //        }
        //        sr.Close();

        //        foreach (ListViewItem item in FormLogList.GetListViewItemCollection())
        //        {
        //            DefinitionProcessor def = (DefinitionProcessor)item.Tag;
        //            item.Checked = list.Contains(def.Reader.FileName);
        //        }


        //    }
        //    else
        //    {

        //        foreach (ListViewItem item in FormLogList.GetListViewItemCollection())
        //        {
        //            DefinitionProcessor def = (DefinitionProcessor)item.Tag;

        //            string query = string.Format("WHERE opcode IN ( {0}, {1}, {2}, {3})", 239, 240, 241, 812);

        //            int count = def.Reader.GetTotalByQuery(query);


        //            item.Checked = count > 0;



        //        }

        //        System.IO.StreamWriter sw = new System.IO.StreamWriter("customlist.log");

        //        foreach (DefinitionProcessor def in FormLogList.CheckedItems)
        //        {
        //            sw.WriteLine(def.Reader.FileName);
        //        }

        //        sw.Close();
        //    }

        //}

        private void btnPauseResume_Click(object sender, EventArgs e)
        {
            StaticObjects.eventManager.Pause = !StaticObjects.eventManager.Pause;
            if (!StaticObjects.eventManager.Pause)
            {
                StaticObjects.eventManager.Pause = false;
                btnPauseResume.Text = "Pause";
                ProcessThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ProcessLogs));
                ProcessLogsArgs param = new ProcessLogsArgs() { definitionProcessorArray = FormLogList.CheckedItems, resume = true };
                ProcessThread.Start((object)param);
            }
            else
            {
                StaticObjects.eventManager.Pause = true;
                btnPauseResume.Text = "Resume";
            }
        }

        private void btnLogIt_CheckedChanged(object sender, EventArgs e)
        {
            StaticObjects.eventManager.LogIt = btnLogIt.Checked;
        }

        private void txtRadarRefreshRate_TextChanged(object sender, EventArgs e)
        {
            StaticObjects.RadarRefreshRate = txtRadarRefreshRate.Text.GetIntOrZero();
        }

 

        //private void toolStripButton1_Click_2(object sender, EventArgs e)
        //{
        //    //if (System.IO.File.Exists("DynamicDefinitionMain.xml")) System.IO.File.Move("DynamicDefinitionMain.xml", DateTime.Now.ToString("MM-dd-yyy-hh-ss-mm-nn") + "_DynamicDefinitionMain.xml");

        //    //PACKETPARSERMAX20.CORE.DynamicDefinitionMain tDynDefMain = new DynamicDefinitionMain();

        //    //tDynDefMain.DynamicDefinitionInfos = new DynamicDefinitionMain.DynamicDefinitionInfoCol();
        //    //PACKETPARSERMAX20.CORE.DynamicDefinitionInfo tItem_Template = new DynamicDefinitionInfo();
        //    //tDynDefMain.DynamicDefinitionInfos.Add(tItem_Template);
        //    //tItem_Template.Fields = new DynamicDefinitionInfo.FieldCol();
        //    //tItem_Template.AddField("ItemID", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("Class", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("SubClass", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("Unk0", typeof(UInt32), 1, 0, 0, "new 2.0.3, not exist in wdb cache?");
        //    //tItem_Template.AddField("Name1", typeof(String), 1, 0, 0);
        //    //tItem_Template.AddField("Name2", typeof(String), 1, 0, 0);
        //    //tItem_Template.AddField("Name3", typeof(String), 1, 0, 0);
        //    //tItem_Template.AddField("Name4", typeof(String), 1, 0, 0);
        //    //tItem_Template.AddField("DisplayInfoID", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("Quality", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("Flags", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("Faction", typeof(UInt32), 1, 10314, 0);
        //    //tItem_Template.AddField("BuyPrice", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("SellPrice", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("InventoryType", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("AllowableClass", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("AllowableRace", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("ItemLevel", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("RequiredLevel", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("RequiredSkill", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("RequiredSkillRank", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("RequiredSpell", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("RequiredSpell", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("RequiredCityRank", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("RequiredReputationFaction", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("RequiredReputationRank", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("MaxCount", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("Stackable", typeof(UInt32), 1, 0, 0);
        //    //tItem_Template.AddField("ContainerSlots", typeof(UInt32), 1, 0, 0);

        //    //DynamicDefinitionInfo.Field tStatsCountField1 = tItem_Template.AddField("StatsCount", typeof(UInt32), 0, 9183, 0);
        //    //DynamicDefinitionInfo.Field tStatsCountField2 = tItem_Template.AddField("StatsCount", typeof(UInt32), 10, 0, 9183 - 1);

        //    //tStatsCountField1.SubFields = new DynamicDefinitionInfo.FieldCol();
        //    //tStatsCountField1.SubFields.AddField("ItemStatType", typeof(UInt32), 1, 0, 0);
        //    //tStatsCountField1.SubFields.AddField("ItemStatValue", typeof(UInt32), 1, 0, 0);

        //    //tStatsCountField2.SubFields = new DynamicDefinitionInfo.FieldCol();
        //    //tStatsCountField2.SubFields.AddField("ItemStatType", typeof(UInt32), 1, 0, 0);
        //    //tStatsCountField2.SubFields.AddField("ItemStatValue", typeof(UInt32), 1, 0, 0);

        //    //tItem_Template.AddField("ScalingStatDistribution", typeof(UInt32), 1, 9183, 0, "scaling stats distribution");
        //    //tItem_Template.AddField("ScalingStatValue", typeof(UInt32), 1, 9183, 0, "some kind of flags used to determine stat values column");

        //    //DynamicDefinitionInfo.Field tDamageField1 = tItem_Template.AddField("Damage", typeof(UInt32), 2, 0, 9551);
        //    //DynamicDefinitionInfo.Field tDamageField2 = tItem_Template.AddField("Damage", typeof(UInt32), 5, 0, 9551 - 1);

        //    //proto.Damage = new List<_Damage>();
        //    //UInt32 DamageCount = 5;
        //    //if (ClientBuild > 9551)
        //    //{
        //    //    DamageCount = 2;
        //    //}
        //    //for (int i = 0; i < DamageCount; i++)
        //    //{
        //    //    _Damage t_Damage = new _Damage();

        //    //    t_Damage.DamageMin = ReadSingle();
        //    //    t_Damage.DamageMax = ReadSingle();
        //    //    t_Damage.DamageType = ReadUInt32();

        //    //    proto.Damage.Add(t_Damage);
        //    //}

        //    //// resistances (7)
        //    //proto.Armor = ReadUInt32();
        //    //proto.HolyRes = ReadUInt32();
        //    //proto.FireRes = ReadUInt32();
        //    //proto.NatureRes = ReadUInt32();
        //    //proto.FrostRes = ReadUInt32();
        //    //proto.ShadowRes = ReadUInt32();
        //    //proto.ArcaneRes = ReadUInt32();

        //    //proto.Delay = ReadUInt32();
        //    //proto.Ammo_type = ReadUInt32();
        //    //proto.RangedModRange = ReadSingle();

        //    //proto.Spells = new List<_Spell>(5);
        //    //for (int s = 0; s < 5; s++)
        //    //{
        //    //    // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
        //    //    // use `item_template` or if not set then only use spell cooldowns
        //    //    _Spell t_Spell = new _Spell();

        //    //    t_Spell.SpellId = ReadUInt32();
        //    //    t_Spell.SpellTrigger = ReadUInt32();
        //    //    t_Spell.SpellCharges = ReadInt32();
        //    //    t_Spell.SpellCooldown = ReadInt32();
        //    //    t_Spell.SpellCategory = ReadUInt32();
        //    //    t_Spell.SpellCategoryCooldown = ReadInt32();

        //    //    proto.Spells.Add(t_Spell);
        //    //}
        //    //proto.Bonding = ReadUInt32();
        //    //proto.Description = ReadString();
        //    //proto.PageText = ReadUInt32();
        //    //proto.LanguageID = ReadUInt32();
        //    //proto.PageMaterial = ReadUInt32();
        //    //proto.StartQuest = ReadUInt32();
        //    //proto.LockID = ReadUInt32();
        //    //proto.Material = ReadUInt32();
        //    //proto.Sheath = ReadUInt32();
        //    //proto.RandomProperty = ReadUInt32();
        //    //proto.RandomSuffix = ReadUInt32();
        //    //proto.Block = ReadUInt32();
        //    //proto.ItemSet = ReadUInt32();
        //    //proto.MaxDurability = ReadUInt32();
        //    ////Added in 1.12.x & 2.0.1 client branch
        //    ////if (ClientBuild < 8089)
        //    ////{
        //    //proto.Area = ReadUInt32();//proto.Area;
        //    //proto.Map = ReadUInt32();//proto.Map;                                // Added in 1.12.x & 2.0.1 client branch
        //    ////}
        //    //proto.BagFamily = ReadUInt32();
        //    //proto.TotemCategory = ReadUInt32();

        //    //proto.Socket = new List<_Socket>(3);
        //    //for (int s = 0; s < 3; s++)
        //    //{
        //    //    _Socket t_Socket = new _Socket();
        //    //    t_Socket.Color = ReadUInt32();
        //    //    t_Socket.Content = ReadUInt32();
        //    //    proto.Socket.Add(t_Socket);
        //    //}
        //    //proto.socketBonus = ReadUInt32();
        //    //if (ClientBuild >= 7561)
        //    //{
        //    //    proto.GemProperties = ReadUInt32();
        //    //}

        //    //if (ClientBuild <= 7799)
        //    //{
        //    //    proto.ExtendedCost = ReadUInt32();
        //    //    proto.RequiredArenaRank = ReadUInt32();
        //    //}
        //    //proto.RequiredDisenchantSkill = ReadUInt32();
        //    //proto.ArmorDamageModifier = ReadSingle();

        //    //if (ClientBuild >= 8209)
        //    //{
        //    //    proto.Duration = ReadInt32();// added in 2.4.2.8209, duration (seconds)
        //    //}


        //    //if (ClientBuild >= 9183)
        //    //{
        //    //    proto.ItemLimitCategory = ReadUInt32();

        //    //}

        //    //if (ClientBuild > 9551)
        //    //{

        //    //    proto.HolidayId = ReadUInt32();
        //    //}






        //}


    }
}




////////  using System;
////////using System.Collections.Generic;
////////using System.Text;

////////namespace Utilities
////////{
////////    public class MyHexConverter
////////    {
////////        /// <summary>
////////        /// Helper array to speedup conversion
////////        /// </summary>
////////        static string[] BATHS = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" };
////////        static byte[] HSTB = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15 };
////////        /// <summary>
////////        /// Function converts byte array to it's hexadecimal implementation
////////        /// </summary>
////////        /// <param name="ArrayToConvert">Array to be converted</param>
////////        /// <param name="Delimiter">Delimiter to be inserted between bytes</param>
////////        /// <returns>String to represent given array</returns>
////////        public static string ByteArrayToHexString(byte[] ArrayToConvert, string Delimiter)
////////        {
////////            int LengthRequired = ArrayToConvert.Length << 1 + Delimiter.Length * ArrayToConvert.Length + 1;
////////            StringBuilder tempstr = new StringBuilder(LengthRequired, LengthRequired);
////////            foreach (byte CurrentElem in ArrayToConvert)
////////            {
////////                tempstr.Append(BATHS[CurrentElem]);
////////                tempstr.Append(Delimiter);
////////            }
////////            tempstr.Remove(tempstr.Length - 1, 1);
////////            return tempstr.ToString();
////////        }


////////        /// <summary>
////////        /// Function converts given hexadecimal string to it's binary representation
////////        /// </summary>
////////        /// <param name="StringToConvert">String to convert to byte array</param>
////////        /// <returns>Byte array representing given string</returns>
////////        public static byte[] PureHexStringToByteArray(string StringToConvert)
////////        {
////////            byte[] temparr = new byte[StringToConvert.Length / 2];
////////            byte Char1, Char2;
////////            for (int i = 0; i < StringToConvert.Length; i = i + 2)
////////            {
////////                Char1 = (Byte)StringToConvert[i];
////////                Char2 = (Byte)StringToConvert[i + 1];
////////                temparr[i / 2] = (Byte)((HSTB[(Char1 - 48)] << 4) + HSTB[(Char2 - 48)]);
////////            }
////////            return temparr;
////////        }
////////    }
////////} 


